import { useRouter, RouteLocationRaw } from "vue-router";
import { isExternalUrl } from "@/utils/is";
import { logger } from "@/utils/logger";

/**
 * 导航选项接口
 * @typedef {Object} NavigateOptions
 * @property {boolean} [newTab] - 是否在新标签页中打开（仅对外链有效）
 * @property {Function} [onBefore] - 导航前的回调函数，返回 false 将阻止导航
 * @property {Function} [onError] - 导航失败时的回调函数
 */

/**
 * 导航到指定目标
 * @param target - 导航目标，可以是URL字符串或路由对象
 * @param options - 导航选项
 * @returns 返回一个Promise，表示导航是否成功
 *
 * @example
 * // 导航到内部路由
 * navigateTo('/dashboard');
 *
 * @example
 * // 导航到外部链接，在新标签页打开
 * navigateTo('https://example.com', { newTab: true });
 *
 * @example
 * // 导航前执行确认操作
 * navigateTo('/profile', {
 *   onBefore: () => confirm('确定要离开当前页面吗？')
 * });
 */
export const navigateTo = async (target, options = {}) => {
    try {
        // 注意：useRouter 应该在 setup 函数或组合式函数中使用
        // 这里假设在组件外部使用，实际使用时可能需要调整
        const router = useRouter();
        const { newTab = true, onBefore } = options;
        // 执行导航前回调
        if (onBefore) {
            const shouldContinue = await Promise.resolve(onBefore());
            if (!shouldContinue) return false;
        }

        // 处理外部链接
        if (typeof target === "string" && isExternalUrl(target)) {
            // 使用 window.open 打开外部链接
            const newWindow = window.open(target, newTab ? "_blank" : "_self");

            // 检查是否成功打开窗口（可能被浏览器拦截）
            if (newWindow === null) {
                throw new Error("无法打开新窗口，可能被浏览器拦截");
            }
        } else {
            // 使用 vue-router 导航到内部路由
            await router.push(target);
        }

        return true;
    } catch (error) {
        // 记录错误日志
        logger.error("导航失败:", error);

        // 如果提供了错误回调，则执行
        if (options.onError) {
            options.onError(error);
        }

        return false;
    }
};

/**
 * 返回上一页，如果没有历史记录则导航到指定的回退URL
 * @param fallbackUrl - 当无法返回上一页时的回退URL
 * @param options - 导航选项
 * @returns 返回一个Promise，表示导航是否成功
 *
 * @example
 * // 简单返回上一页
 * goBack();
 *
 * @example
 * // 返回上一页，如果没有历史则跳转到首页
 * goBack('/home');
 *
 * @example
 * // 返回前进行确认
 * goBack('/home', {
 *   onBefore: () => confirm('确定要返回吗？')
 * });
 */
export const goBack = async (fallbackUrl, options = {}) => {
    try {
        const router = useRouter();
        const { onBefore } = options;

        // 执行导航前回调
        if (onBefore) {
            const shouldContinue = await Promise.resolve(onBefore());
            if (!shouldContinue) return false;
        }

        // 检查历史记录
        if (window.history.length > 1) {
            router.back();
        } else if (fallbackUrl) {
            // 如果没有历史记录，则导航到回退URL
            await router.push(fallbackUrl);
        } else {
            // 既没有历史记录也没有回退URL
            logger.warn("无法返回上一页：没有历史记录且未提供回退URL");
            return false;
        }

        return true;
    } catch (error) {
        // 记录错误日志
        logger.error("返回上一页失败:", error);

        // 如果提供了错误回调，则执行
        if (options.onError) {
            options.onError(error);
        }

        return false;
    }
};

/**
 * 在当前页面中替换路由，不会新增历史记录
 * @param target - 导航目标，可以是URL字符串或路由对象
 * @param options - 导航选项
 * @returns 返回一个Promise，表示导航是否成功
 *
 * @example
 * // 替换当前路由
 * replaceRoute('/new-page');
 */
export const replaceRoute = async (target, options = {}) => {
    try {
        const router = useRouter();
        const { onBefore } = options;

        // 执行导航前回调
        if (onBefore) {
            const shouldContinue = await Promise.resolve(onBefore());
            if (!shouldContinue) return false;
        }

        // 使用 replace 方法替换当前路由
        await router.replace(target);
        return true;
    } catch (error) {
        // 记录错误日志
        logger.error("替换路由失败:", error);

        // 如果提供了错误回调，则执行
        if (options.onError) {
            options.onError(error);
        }

        return false;
    }
};